use std::{collections::HashMap, ops::Deref};
use std::ops::DerefMut;

use rand::seq::SliceRandom;

#[derive(Clone, PartialEq, Eq)]
pub struct Service {
    pub host: String,
    pub port: i32,
    pub name: String,
}

impl Service {
    #[inline]
    pub fn get_url(&self) -> String {
        format!("{}:{}", self.host, self.port)
    }
}

#[derive(Default)]
pub struct ServiceBook(HashMap<String, Vec<Service>>);

impl Deref for ServiceBook {
    type Target = HashMap<String, Vec<Service>>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for ServiceBook {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl ServiceBook {
    pub fn new() -> Self {
        Self::default()
    }
    /// 添加服务端
    #[inline]
    pub fn join_service(
        &mut self,
        service_book_name: String,
        service: Service,
    ) -> Result<(), Box<dyn std::error::Error>> {
        match self.get_mut(service_book_name.as_str()) {
            None => {
                self.insert(service_book_name, vec![service]);
            }
            Some(senders) => {
                senders.insert(0, service);
            }
        };
        Ok(())
    }
    /// 获取服务端
    #[inline]
    pub fn get_service(&self, service_book_name: String) -> Option<Vec<Service>> {
        self.get(service_book_name.as_str()).map(|services| services.to_vec())
    }
    /// 随机获取一个服务
    #[inline]
    pub fn choose_service(&self, service_book_name: String) -> Option<Service> {
        self.get_service(service_book_name)?.choose(&mut rand::thread_rng()).cloned()
    }
}
